Meistern Sie die User Timing API für aussagekräftige Performance-Metriken. Finden Sie Engpässe jenseits von Web Vitals und optimieren Sie die User Experience.
Frontend-Performance meistern: Ein tiefer Einblick in die User Timing API
In der modernen digitalen Landschaft ist Frontend-Performance kein Luxus, sondern eine grundlegende Voraussetzung für den Erfolg. Für ein globales Publikum kann eine langsame, nicht reagierende Website zu Frustration bei den Nutzern, geringerem Engagement und direkten negativen Auswirkungen auf die Geschäftsergebnisse führen. Wir haben hervorragende standardisierte Metriken wie die Core Web Vitals (Largest Contentful Paint, First Input Delay, Cumulative Layout Shift), die uns ein grundlegendes Verständnis der User Experience vermitteln. Diese Metriken sind zwar entscheidend, erzählen aber nur einen Teil der Geschichte.
Was ist mit der Performance anwendungsspezifischer Funktionen? Wie lange dauert es, bis Suchergebnisse erscheinen, nachdem ein Nutzer eine Anfrage eingegeben hat? Wie viel Zeit benötigt Ihre komplexe Datenvisualisierungskomponente zum Rendern, nachdem sie Daten von einer API erhalten hat? Wie wirkt sich ein neues Feature auf die Geschwindigkeit der Routen-Übergänge Ihrer Single-Page Application (SPA) aus? Standardmetriken können diese granularen, geschäftskritischen Fragen nicht beantworten. Hier kommt die User Timing API ins Spiel, die Entwicklern die Möglichkeit gibt, benutzerdefinierte, hochpräzise Leistungsmessungen zu erstellen, die auf ihre einzigartigen Anwendungen zugeschnitten sind.
Dieser umfassende Leitfaden führt Sie durch alles, was Sie wissen müssen, um die User Timing API zu nutzen – von den grundlegenden Konzepten von Marks und Measures bis hin zu fortgeschrittenen Techniken mit dem PerformanceObserver. Am Ende werden Sie in der Lage sein, über generische Metriken hinauszugehen und die einzigartige Performance-Geschichte Ihrer Anwendung zu erzählen.
Was ist die Performance API? Ein breiterer Kontext
Bevor wir tief in User Timing eintauchen, ist es wichtig zu verstehen, dass es Teil einer größeren Sammlung von Werkzeugen ist, die zusammen als Performance API bekannt sind. Diese Browser-API bietet Zugriff auf hochpräzise Zeitdaten in Bezug auf Navigation, das Laden von Ressourcen und mehr. Das globale `window.performance`-Objekt ist Ihr Einstiegspunkt in dieses leistungsstarke Toolset.
Die Performance API besteht aus mehreren Schnittstellen, darunter:
- Navigation Timing: Bietet detaillierte Zeitinformationen über den Navigationsprozess des Dokuments, wie z.B. die Zeit für DNS-Lookups, TCP-Handshakes und den Empfang des ersten Bytes.
- Resource Timing: Bietet detaillierte Netzwerk-Zeitdaten für jede von der Seite geladene Ressource, einschließlich Bildern, Skripten und CSS-Dateien.
- Paint Timing: Stellt Zeitmessungen für First Paint und First Contentful Paint bereit.
- User Timing: Der Schwerpunkt unseres Artikels, der es Entwicklern ermöglicht, ihre eigenen benutzerdefinierten Zeitstempel (Marks) zu erstellen und die Dauer zwischen ihnen zu messen (Measures).
Diese APIs arbeiten zusammen, um eine ganzheitliche Sicht auf die Leistung Ihrer Anwendung zu ermöglichen. Unser heutiges Ziel ist es, den User-Timing-Teil zu meistern, der uns die Möglichkeit gibt, unsere eigenen benutzerdefinierten Kontrollpunkte zu dieser Performance-Timeline hinzuzufügen.
Die Kernkonzepte: Marks und Measures
Die User Timing API ist täuschend einfach und dreht sich um zwei grundlegende Konzepte: marks und measures. Stellen Sie es sich wie die Verwendung einer Stoppuhr vor. Sie drücken eine Taste, um eine Startzeit zu markieren, und drücken sie erneut, um eine Endzeit zu markieren. Die Dauer zwischen diesen beiden Drücken ist Ihre Messung.
Performance-Marks erstellen: `performance.mark()`
Ein 'Mark' ist ein benannter, hochauflösender Zeitstempel, der an einem bestimmten Punkt in der Ausführung Ihrer Anwendung aufgezeichnet wird. Es ist, als würde man eine Flagge auf seiner Performance-Timeline platzieren. Sie können so viele Marks erstellen, wie Sie benötigen, um Schlüsselmomente in einer User Journey oder einem Komponenten-Lebenszyklus zu identifizieren.
Die Syntax ist unkompliziert:
performance.mark(markName, [markOptions]);
markName: Ein String, der den eindeutigen Namen für Ihren Mark darstellt. Wählen Sie beschreibende Namen!markOptions(optional): Ein Objekt, das einedetail-Eigenschaft zum Anhängen zusätzlicher Metadaten und einestartTimezur Angabe eines benutzerdefinierten Zeitstempels enthalten kann.
Grundlegendes Beispiel: Markieren eines Ereignisses
Angenommen, wir möchten den Beginn eines wichtigen Funktionsaufrufs markieren.
function processLargeDataset() {
// Plant a flag right before the heavy work begins
performance.mark('processLargeDataset:start');
// ... heavy computational logic ...
console.log('Dataset processing complete.');
// Plant another flag when it's done
performance.mark('processLargeDataset:end');
}
processLargeDataset();
In diesem Beispiel haben wir zwei Zeitstempel in der Performance-Timeline des Browsers erstellt: `processLargeDataset:start` und `processLargeDataset:end`. Im Moment sind sie nur Zeitpunkte. Ihre wahre Stärke wird entfaltet, wenn wir sie verwenden, um eine Messung (Measure) zu erstellen.
Kontext mit der `detail`-Eigenschaft hinzufügen
Manchmal ist ein Zeitstempel allein nicht ausreichend. Möglicherweise möchten Sie zusätzlichen Kontext darüber einfügen, was in diesem Moment geschah. Die `detail`-Eigenschaft ist dafür perfekt. Sie kann alle Daten aufnehmen, die strukturell geklont werden können (wie Objekte, Arrays, Zeichenketten, Zahlen).
Stellen Sie sich vor, wir markieren den Beginn des Renderns einer Komponente und möchten wissen, wie viele Elemente sie gerendert hat.
function renderProductList(products) {
const itemCount = products.length;
performance.mark('ProductList:render:start', {
detail: {
itemCount: itemCount,
source: 'initial-load'
}
});
// ... component rendering logic ...
performance.mark('ProductList:render:end');
}
const sampleProducts = new Array(1000).fill(0);
renderProductList(sampleProducts);
Dieser zusätzliche Kontext ist bei der späteren Analyse von Leistungsdaten von unschätzbarem Wert. Sie könnten zum Beispiel die Renderzeiten mit der Anzahl der Elemente korrelieren, um zu sehen, ob es eine lineare oder exponentielle Beziehung gibt.
Performance-Measures erstellen: `performance.measure()`
Ein 'Measure' erfasst die Dauer zwischen zwei Zeitpunkten. Es ist die Berechnung, die Ihnen sagt, \"wie lange\" etwas gedauert hat. Am häufigsten werden Sie die Zeit zwischen zwei Ihrer benutzerdefinierten Marks messen.
Die Syntax hat einige Variationen:
performance.measure(measureName, startMarkOrOptions, [endMark]);
measureName: Ein String, der den eindeutigen Namen für Ihre Messung darstellt.startMarkOrOptions(optional): Ein String mit dem Namen des Start-Marks. Kann auch ein Options-Objekt mit `start`, `end`, `duration` und `detail` sein.endMark(optional): Ein String mit dem Namen des End-Marks.
Grundlegendes Beispiel: Messung der Dauer einer Funktion
Bauen wir auf unserem `processLargeDataset`-Beispiel auf und messen tatsächlich, wie lange es gedauert hat.
function processLargeDataset() {
performance.mark('processLargeDataset:start');
// ... heavy computational logic ...
performance.mark('processLargeDataset:end');
// Now, create the measure
performance.measure(
'processLargeDataset:duration',
'processLargeDataset:start',
'processLargeDataset:end'
);
}
processLargeDataset();
Nachdem dieser Code ausgeführt wurde, enthält der Performance-Puffer des Browsers einen neuen Eintrag mit dem Namen `processLargeDataset:duration`. Dieser Eintrag hat eine `duration`-Eigenschaft, die die genaue Zeit in Millisekunden enthält, die zwischen dem Start- und End-Mark vergangen ist.
Fortgeschrittene Messszenarien
Die `measure()`-Methode ist sehr flexibel. Sie müssen nicht immer zwei Marks angeben.
- Vom Navigationsstart bis zu einem Mark: Sie können die Zeit vom Beginn der Seitennavigation bis zu einem Ihrer benutzerdefinierten Marks messen. Dies ist unglaublich nützlich, um Dinge wie \"Time to Interactive Component\" zu messen.
// Measure from navigation start until the main component is ready performance.measure('timeToInteractiveHeader', 'navigationStart', 'headerComponent:ready'); - Von einem Mark bis jetzt: Wenn Sie den `endMark` weglassen, wird die Messung von Ihrem `startMark` bis zur aktuellen Zeit berechnet.
// Measure from the start mark until this line of code is executed performance.measure('timeSinceDataRequest', 'api:fetch:start'); - Verwendung des Options-Objekts: Sie können auch ein Konfigurationsobjekt übergeben, um die Messung zu definieren, was nützlich ist, um eine `detail`-Eigenschaft hinzuzufügen.
performance.measure('complexRender:duration', { start: 'complexRender:start', end: 'complexRender:end', detail: { renderType: 'canvas' } });
Zugriff auf und Löschen von Performance-Einträgen
Das Erstellen von Marks und Measures ist nur die halbe Miete. Sie benötigen eine Möglichkeit, diese Daten abzurufen, um sie zu analysieren. Das `performance`-Objekt bietet hierfür mehrere Methoden.
performance.getEntries(): Gibt ein Array aller Performance-Einträge im Puffer zurück (einschließlich Resource Timings, Navigation Timings usw.).performance.getEntriesByType(type): Gibt ein Array von Einträgen eines bestimmten Typs zurück. Sie werden am häufigsten `performance.getEntriesByType('mark')` und `performance.getEntriesByType('measure')` verwenden.performance.getEntriesByName(name, [type]): Gibt ein Array von Einträgen mit einem bestimmten Namen (und optional einem bestimmten Typ) zurück.
Beispiel: Measures in der Konsole protokollieren
// After running our previous examples...
const allMeasures = performance.getEntriesByType('measure');
console.log(allMeasures);
// A measure entry object looks something like this:
// {
// "name": "processLargeDataset:duration",
// "entryType": "measure",
// "startTime": 12345.67,
// "duration": 150.89
// }
const specificMeasure = performance.getEntriesByName('processLargeDataset:duration');
console.log(`Processing took: ${specificMeasure[0].duration}ms`);
Wichtig: Den Performance-Puffer bereinigen
Der Performance-Puffer des Browsers ist nicht unendlich groß. Um Speicherlecks zu vermeiden und Ihre Messungen relevant zu halten, ist es eine bewährte Vorgehensweise, die von Ihnen erstellten Marks und Measures zu löschen, sobald Sie mit ihnen fertig sind.
performance.clearMarks([name]): Löscht alle Marks oder nur Marks mit dem angegebenen Namen.performance.clearMeasures([name]): Löscht alle Measures oder nur Measures mit dem angegebenen Namen.
Ein gängiges Muster ist, die Daten abzurufen, sie zu verarbeiten oder zu senden und sie dann zu löschen.
function analyzeAndClear() {
const myMeasures = performance.getEntriesByName('processLargeDataset:duration');
// Send myMeasures to an analytics service...
sendToAnalytics(myMeasures);
// Clean up to free memory
performance.clearMarks('processLargeDataset:start');
performance.clearMarks('processLargeDataset:end');
performance.clearMeasures('processLargeDataset:duration');
}
Praktische, reale Anwendungsfälle für User Timing
Nachdem wir die Mechanik verstanden haben, wollen wir untersuchen, wie man die User Timing API anwendet, um reale Performance-Herausforderungen zu lösen. Diese Beispiele sind Framework-unabhängig und können an jeden Frontend-Stack angepasst werden.
1. Messung der Dauer von API-Aufrufen
Zu verstehen, wie lange Ihre Anwendung auf Daten wartet, ist entscheidend. Sie können Ihre Datenabruflogik einfach mit Marks und Measures umschließen.
async function fetchUserData(userId) {
const markStart = `api:getUser:${userId}:start`;
const markEnd = `api:getUser:${userId}:end`;
const measureName = `api:getUser:${userId}:duration`;
performance.mark(markStart);
try {
const response = await fetch(`https://api.example.com/users/${userId}`);
if (!response.ok) {
throw new Error('Network response was not ok');
}
return await response.json();
} catch (error) {
console.error('Fetch error:', error);
// You can even add details about errors!
performance.mark(markEnd, { detail: { status: 'error', message: error.message } });
} finally {
// Ensure the end mark and measure are always created
if (performance.getEntriesByName(markEnd).length === 0) {
performance.mark(markEnd, { detail: { status: 'success' } });
}
performance.measure(measureName, markStart, markEnd);
}
}
fetchUserData('123');
Dieses Muster liefert präzise Zeitmessungen für jeden API-Aufruf und ermöglicht es Ihnen, langsame Endpunkte direkt aus echten Nutzerdaten zu identifizieren.
2. Erfassen von Komponenten-Renderzeiten in SPAs
Für Frameworks wie React, Vue oder Angular ist die Messung der Zeit, die eine Komponente zum Mounten und Rendern benötigt, ein primärer Anwendungsfall. Dies hilft dabei, komplexe Komponenten zu identifizieren, die Ihre Anwendung möglicherweise verlangsamen.
Beispiel mit React Hooks:
import React, { useLayoutEffect, useEffect, useRef } from 'react';
function MyHeavyComponent({ data }) {
const componentId = useRef(`MyHeavyComponent-${Math.random()}`).current;
const markStartName = `${componentId}:render:start`;
const markEndName = `${componentId}:render:end`;
const measureName = `${componentId}:render:duration`;
// useLayoutEffect runs synchronously after all DOM mutations.
// It's the perfect place to mark the start of the render measurement.
useLayoutEffect(() => {
performance.mark(markStartName);
}, []); // Run only on initial mount
// useEffect runs asynchronously after the render is committed to the screen.
// This is a good place to mark the end.
useEffect(() => {
performance.mark(markEndName);
performance.measure(measureName, markStartName, markEndName);
// Log the result for demonstration
const measure = performance.getEntriesByName(measureName)[0];
if (measure) {
console.log(`${measureName} took ${measure.duration}ms`);
}
// Cleanup
performance.clearMarks(markStartName);
performance.clearMarks(markEndName);
performance.clearMeasures(measureName);
}, []); // Run only on initial mount
return (
// ... JSX for the heavy component ...
);
}
3. Quantifizierung kritischer User Journeys
Die wirkungsvollste Anwendung von User Timing ist die Messung mehrstufiger Benutzerinteraktionen, die für Ihr Unternehmen entscheidend sind. Dies geht über einfache technische Metriken hinaus und misst die wahrgenommene Geschwindigkeit der Kernfunktionalität Ihrer Anwendung.
Betrachten Sie einen E-Commerce-Checkout-Prozess:
const checkoutButton = document.getElementById('checkout-btn');
checkoutButton.addEventListener('click', () => {
// 1. User clicks the 'checkout' button
performance.mark('checkout:journey:start');
// ... code to validate cart, navigate to payment page, etc. ...
});
// On the payment page, after the payment form is rendered and interactive
function onPaymentFormReady() {
performance.mark('checkout:paymentForm:ready');
performance.measure('checkout:timeToPaymentForm', 'checkout:journey:start', 'checkout:paymentForm:ready');
}
// After the payment is successfully processed and the confirmation screen is shown
function onPaymentSuccess() {
performance.mark('checkout:journey:end');
performance.measure('checkout:totalJourney:duration', 'checkout:journey:start', 'checkout:journey:end');
// Now you have two powerful metrics to analyze and optimize.
}
4. A/B-Tests von Leistungsverbesserungen
Wenn Sie ein Stück Code refaktorisieren oder einen neuen Algorithmus einführen, wie beweisen Sie, dass er für echte Benutzer tatsächlich schneller ist? User Timing liefert objektive Daten für A/B-Tests.
Stellen Sie sich vor, Sie möchten zwei verschiedene Sortieralgorithmen testen:
function sortProducts(products, algorithmVersion) {
const markStart = `sort:v${algorithmVersion}:start`;
const markEnd = `sort:v${algorithmVersion}:end`;
const measureName = `sort:v${algorithmVersion}:duration`;
performance.mark(markStart);
if (algorithmVersion === 'A') {
// ... run old sorting algorithm ...
} else {
// ... run new, optimized sorting algorithm ...
}
performance.mark(markEnd);
performance.measure(measureName, markStart, markEnd);
}
// Based on an A/B testing flag, you would call one or the other.
// Later, in your analytics, you can compare the average duration of
// 'sort:vA:duration' vs 'sort:vB:duration' to see which was faster.
Visualisierung und Analyse Ihrer benutzerdefinierten Metriken
Das Erstellen benutzerdefinierter Metriken ist nutzlos, wenn Sie die Daten nicht analysieren. Es gibt zwei primäre Ansätze dafür: lokal während der Entwicklung und aggregiert in der Produktion.
Verwendung der Browser-Entwicklertools
Moderne Browser wie Chrome und Firefox bieten hervorragende Unterstützung für die Visualisierung von User-Timing-Marks und -Measures in ihren Performance-Profiling-Tools.
- Öffnen Sie die Entwicklertools Ihres Browsers (F12 oder Strg+Umschalt+I).
- Gehen Sie zum Tab Performance.
- Starten Sie die Aufzeichnung eines Profils und führen Sie dann die Aktionen in Ihrer App aus, die Ihre benutzerdefinierten Marks und Measures auslösen.
- Stoppen Sie die Aufzeichnung.
In der Timeline-Ansicht finden Sie eine dedizierte Zeile namens Timings. Ihre benutzerdefinierten Marks erscheinen als vertikale Linien, und Ihre Measures werden als farbige Balken angezeigt, die ihre Dauer zeigen. Wenn Sie mit der Maus darüber fahren, werden ihre Namen und genauen Zeitangaben angezeigt. Dies ist eine unglaublich leistungsstarke Methode, um Performance-Probleme während der Entwicklung zu debuggen.
Senden von Daten an Analyse- und RUM-Dienste
Für die Produktionsüberwachung müssen Sie diese Daten von Ihren Benutzern sammeln und zur Aggregation und Analyse an einen zentralen Ort senden. Dies ist ein zentraler Bestandteil des Real User Monitoring (RUM).
Der allgemeine Arbeitsablauf ist:
- Sammeln Sie die Performance-Measures, an denen Sie interessiert sind.
- Formatieren Sie sie in eine geeignete Nutzlast (z. B. JSON).
- Senden Sie die Nutzlast an einen Analyse-Endpunkt. Dies kann ein Drittanbieterdienst wie Datadog, New Relic, Sentry oder sogar Google Analytics (über benutzerdefinierte Ereignisse) sein, oder ein von Ihnen kontrolliertes benutzerdefiniertes Backend.
function sendPerformanceData() {
// We only care about our custom application measures
const appMeasures = performance.getEntriesByType('measure').filter(
(entry) => entry.name.startsWith('app:') // Use a naming convention!
);
if (appMeasures.length > 0) {
const payload = JSON.stringify(appMeasures.map(measure => ({
name: measure.name,
duration: measure.duration,
startTime: measure.startTime,
details: measure.detail, // Send our rich context
path: window.location.pathname // Add more context
})));
// Use navigator.sendBeacon for reliable, non-blocking data sending
navigator.sendBeacon('https://analytics.example.com/performance', payload);
// Clean up the measures that have been sent
appMeasures.forEach(measure => {
performance.clearMeasures(measure.name);
// Also clear the associated marks
});
}
}
// Call this function at an appropriate time, e.g., when the page is about to unload
window.addEventListener('visibilitychange', () => {
if (document.visibilityState === 'hidden') {
sendPerformanceData();
}
});
Fortgeschrittene Techniken und Best Practices
Um die User Timing API wirklich zu meistern, werfen wir einen Blick auf einige fortgeschrittene Funktionen und bewährte Vorgehensweisen, die Ihre Instrumentierung robuster und effizienter machen.
Verwendung von `PerformanceObserver` für asynchrone Überwachung
Die `getEntries*()`-Methoden erfordern, dass Sie den Performance-Puffer manuell abfragen. Dies hat zwei Nachteile: Sie könnten Ihre Überprüfung zu spät durchführen und Einträge verpassen, wenn der Puffer vollgelaufen und geleert wurde, und das Abfragen selbst kann geringfügige Leistungseinbußen verursachen. Die moderne, bevorzugte Lösung ist der `PerformanceObserver`.
Ein `PerformanceObserver` ermöglicht es Ihnen, Performance-Eintrag-Ereignisse zu abonnieren. Ihre Callback-Funktion wird asynchron aufgerufen, sobald neue Einträge der von Ihnen beobachteten Typen aufgezeichnet werden.
// 1. Create a callback function to handle new entries
const observerCallback = (list) => {
for (const entry of list.getEntries()) {
console.log('New measure observed:', entry.name, entry.duration);
// Here you can immediately send the entry to your analytics service
// without needing to poll or wait.
}
};
// 2. Create the observer instance
const observer = new PerformanceObserver(observerCallback);
// 3. Start observing for 'mark' and 'measure' entry types
// The 'buffered: true' option ensures you get entries that were created
// *before* the observer was registered.
observer.observe({ entryTypes: ['mark', 'measure'], buffered: true });
// Now, any time performance.mark() or performance.measure() is called anywhere
// in your application, the observerCallback will be triggered with the new entry.
// To stop observing later:
// observer.disconnect();
Die Verwendung des `PerformanceObserver` ist effizienter, zuverlässiger und sollte Ihre Standardwahl für das Sammeln von Leistungsdaten in einer Produktionsumgebung sein.
Etablieren Sie eine klare Namenskonvention
Wenn Ihre Anwendung wächst, werden Sie viele benutzerdefinierte Metriken ansammeln. Ohne eine konsistente Namenskonvention werden Ihre Daten schwer zu filtern und zu analysieren sein. Übernehmen Sie ein Muster, das Kontext bietet.
Eine gute Konvention könnte sein: [appName]:[featureOrComponent]:[eventName]:[status]
ecom:ProductGallery:render:startecom:ProductGallery:render:endecom:ProductGallery:render:durationadmin:DataTable:fetchApi:startadmin:DataTable:fetchApi:duration
Diese Struktur macht es trivial, nach allen Metriken zu filtern, die sich auf die `ProductGallery` beziehen, oder alle `fetchApi`-Dauern in der gesamten Anwendung zu finden.
Abstraktion in einen Utility-Service
Um Konsistenz zu gewährleisten und Boilerplate-Code zu reduzieren, kapseln Sie die `performance`-Aufrufe in Ihrem eigenen Utility-Modul oder Service. Dies macht es auch einfach, die Leistungsüberwachung je nach Umgebung zu aktivieren oder zu deaktivieren.
// performance-service.js
const IS_PERFORMANCE_MONITORING_ENABLED = process.env.NODE_ENV === 'production' || window.location.search.includes('perf=true');
export const perfMark = (name, options) => {
if (!IS_PERFORMANCE_MONITORING_ENABLED) return;
performance.mark(name, options);
};
export const perfMeasure = (name, start, end) => {
if (!IS_PERFORMANCE_MONITORING_ENABLED) return;
performance.measure(name, start, end);
};
export const startJourney = (name) => {
perfMark(`${name}:start`);
};
export const endJourney = (name) => {
const startMark = `${name}:start`;
const endMark = `${name}:end`;
const measureName = `${name}:duration`;
perfMark(endMark);
perfMeasure(measureName, startMark, endMark);
// Optionally clear the marks here
};
// In your component:
// import { startJourney, endJourney } from './performance-service';
// startJourney('ecom:checkout');
// ...later...
// endJourney('ecom:checkout');
Fazit: Übernehmen Sie die Kontrolle über die Performance-Geschichte Ihrer Anwendung
Während Standardmetriken wie die Core Web Vitals eine wesentliche Zustandsprüfung für Ihre Website bieten, beleuchten sie nicht die Leistung der Funktionen und Interaktionen, die Ihre Anwendung einzigartig machen. Die User Timing API ist die Brücke, die diese Lücke schließt. Sie bietet einen einfachen, aber dennoch außerordentlich leistungsstarken Mechanismus, um zu messen, was für Ihre Benutzer und Ihr Unternehmen wirklich zählt.
Durch die Implementierung benutzerdefinierter Marks und Measures verwandeln Sie die Leistungsoptimierung von einem Ratespiel in eine datengesteuerte Wissenschaft. Sie können genau die Funktionen, Komponenten oder Benutzerabläufe identifizieren, die Engpässe verursachen, die Auswirkungen Ihrer Refactoring-Bemühungen mit objektiven Zahlen validieren und letztendlich eine schnellere, angenehmere Erfahrung für Ihr globales Publikum schaffen.
Fangen Sie klein an. Identifizieren Sie die eine, kritischste User Journey in Ihrer Anwendung – sei es die Suche nach einem Produkt, das Absenden eines Formulars oder das Laden eines Daten-Dashboards. Instrumentieren Sie sie mit `performance.mark()` und `performance.measure()`. Analysieren Sie die Ergebnisse in Ihren Entwicklertools. Sobald Sie die Klarheit sehen, die dies bietet, werden Sie befähigt sein, die vollständige Performance-Geschichte Ihrer Anwendung zu erzählen, eine benutzerdefinierte Metrik nach der anderen.